package com.agrimall.util;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.io.IOUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 文件上传下载工具类
 */
public class FileUploadUtil {
    
    // 上传文件保存路径（相对于项目resources目录）
    private static final String UPLOAD_PATH = "upload";
    
    // 允许上传的图片类型
    private static final Set<String> ALLOWED_IMAGE_TYPES = new HashSet<>(Arrays.asList(
        "image/jpeg", "image/jpg", "image/png", "image/gif", "image/bmp", "image/webp"
    ));
    
    // 最大文件大小（5MB）
    private static final long MAX_FILE_SIZE = 5 * 1024 * 1024;
    
    /**
     * 获取上传文件保存的绝对路径（项目源码目录下的src/main/resources/upload）
     */
    public static String getUploadPath(HttpServletRequest request) {
        String projectRoot = null;
        
        // 方法0：先从配置文件读取项目根目录（如果配置了）
        try {
            InputStream is = FileUploadUtil.class.getClassLoader().getResourceAsStream("db.properties");
            if (is != null) {
                Properties props = new Properties();
                props.load(is);
                String configuredRoot = props.getProperty("upload.project.root");
                if (configuredRoot != null && !configuredRoot.trim().isEmpty()) {
                    File rootDir = new File(configuredRoot.trim());
                    if (rootDir.exists() && new File(rootDir, "pom.xml").exists()) {
                        projectRoot = rootDir.getAbsolutePath();
                    }
                }
                is.close();
            }
        } catch (Exception e) {
            // 忽略异常，继续使用自动检测
        }
        
        // 方法1：通过类路径查找（适用于IDE和Tomcat部署）
        if (projectRoot == null || projectRoot.isEmpty() || !new File(projectRoot, "pom.xml").exists()) {
            try {
                // 获取当前类的类文件路径
                String classPath = FileUploadUtil.class.getProtectionDomain()
                        .getCodeSource().getLocation().getPath();
                
                // 处理URL编码
                try {
                    classPath = URLDecoder.decode(classPath, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    // 忽略
                }
                
                // 处理Windows路径：如果以/开头，去掉它（如 /C:/path）
                if (classPath.startsWith("/") && classPath.length() > 1 && classPath.charAt(2) == ':') {
                    classPath = classPath.substring(1);
                }
                
                File classFile = new File(classPath);
                
                // 情况1：如果路径指向target/classes（IDE运行时）
                if (classPath.contains("target" + File.separator + "classes") || 
                    classPath.contains("target/classes")) {
                    // 向上查找，直到找到包含pom.xml的目录
                    File currentDir = classFile.getParentFile(); // target/classes
                    if (currentDir != null) {
                        currentDir = currentDir.getParentFile(); // target
                        if (currentDir != null) {
                            currentDir = currentDir.getParentFile(); // 项目根目录
                            if (currentDir != null && new File(currentDir, "pom.xml").exists()) {
                                projectRoot = currentDir.getAbsolutePath();
                            }
                        }
                    }
                }
                // 情况2：如果路径指向WEB-INF/classes（Tomcat部署）
                else if (classPath.contains("WEB-INF" + File.separator + "classes") || 
                         classPath.contains("WEB-INF/classes")) {
                    // 从WEB-INF/classes向上查找项目根目录
                    // 路径可能是：webapps/agri_mall/WEB-INF/classes 或 target/agri_mall/WEB-INF/classes
                    File currentDir = classFile.getParentFile(); // WEB-INF/classes
                    if (currentDir != null) {
                        currentDir = currentDir.getParentFile(); // WEB-INF
                        if (currentDir != null) {
                            currentDir = currentDir.getParentFile(); // agri_mall (webapps下) 或 target
                            if (currentDir != null) {
                                // 如果是webapps下的项目，需要继续向上找到项目源码目录
                                if (currentDir.getName().equals("agri_mall") || 
                                    currentDir.getName().equals("agri_mall.war")) {
                                    // 尝试在常见位置查找项目源码目录
                                    File webappsDir = currentDir.getParentFile(); // webapps
                                    if (webappsDir != null && webappsDir.getName().equals("webapps")) {
                                        // 尝试在Tomcat同级目录或常见开发目录查找
                                        File tomcatDir = webappsDir.getParentFile(); // apache-tomcat-xxx
                                        if (tomcatDir != null) {
                                            // 尝试在Desktop、workspace等常见位置查找
                                            String[] commonPaths = {
                                                System.getProperty("user.home") + File.separator + "Desktop" + File.separator + "agri_mall",
                                                System.getProperty("user.home") + File.separator + "workspace" + File.separator + "agri_mall",
                                                "C:" + File.separator + "Users" + File.separator + "Administrator" + File.separator + "Desktop" + File.separator + "agri_mall"
                                            };
                                            for (String commonPath : commonPaths) {
                                                File testRoot = new File(commonPath);
                                                if (testRoot.exists() && new File(testRoot, "pom.xml").exists()) {
                                                    projectRoot = testRoot.getAbsolutePath();
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                                // 如果是target目录，向上找到项目根目录
                                else if (currentDir.getName().equals("target")) {
                                    File rootDir = currentDir.getParentFile();
                                    if (rootDir != null && new File(rootDir, "pom.xml").exists()) {
                                        projectRoot = rootDir.getAbsolutePath();
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                // 忽略异常，尝试其他方法
            }
        }
        
        // 方法2：通过类加载器获取resources路径
        if (projectRoot == null || projectRoot.isEmpty() || !new File(projectRoot, "pom.xml").exists()) {
            try {
                java.net.URL resourceUrl = FileUploadUtil.class.getClassLoader().getResource("");
                if (resourceUrl != null) {
                    String path = resourceUrl.getPath();
                    
                    // 处理URL编码
                    try {
                        path = URLDecoder.decode(path, "UTF-8");
                    } catch (UnsupportedEncodingException e) {
                        // 忽略
                    }
                    
                    // 处理Windows路径
                    if (path.startsWith("/") && path.length() > 1 && path.charAt(2) == ':') {
                        path = path.substring(1);
                    }
                    
                    // 查找target目录
                    int targetIndex = -1;
                    if (path.contains("target" + File.separator + "classes")) {
                        targetIndex = path.indexOf("target" + File.separator + "classes");
                    } else if (path.contains("target/classes")) {
                        targetIndex = path.indexOf("target/classes");
                    }
                    
                    if (targetIndex > 0) {
                        String rootPath = path.substring(0, targetIndex);
                        File rootDir = new File(rootPath);
                        if (rootDir.exists() && new File(rootDir, "pom.xml").exists()) {
                            projectRoot = rootDir.getAbsolutePath();
                        }
                    }
                }
            } catch (Exception e) {
                // 忽略异常
            }
        }
        
        // 方法3：尝试从类路径中查找（通过java.class.path系统属性）
        if (projectRoot == null || projectRoot.isEmpty() || !new File(projectRoot, "pom.xml").exists()) {
            try {
                String classPath = System.getProperty("java.class.path");
                if (classPath != null) {
                    String[] paths = classPath.split(File.pathSeparator);
                    for (String cp : paths) {
                        if (cp.contains("agri_mall")) {
                            File cpFile = new File(cp);
                            // 如果是jar文件，获取其目录
                            if (cpFile.isFile() && cpFile.getName().endsWith(".jar")) {
                                cpFile = cpFile.getParentFile();
                            }
                            // 向上查找target目录
                            File current = cpFile;
                            while (current != null) {
                                if (current.getName().equals("target")) {
                                    File root = current.getParentFile();
                                    if (root != null && new File(root, "pom.xml").exists()) {
                                        projectRoot = root.getAbsolutePath();
                                        break;
                                    }
                                }
                                current = current.getParentFile();
                            }
                            if (projectRoot != null && new File(projectRoot, "pom.xml").exists()) {
                                break;
                            }
                        }
                    }
                }
            } catch (Exception e) {
                // 忽略异常
            }
        }
        
        // 方法4：尝试常见项目位置（作为最后手段）
        if (projectRoot == null || projectRoot.isEmpty() || !new File(projectRoot, "pom.xml").exists()) {
            String[] commonPaths = {
                System.getProperty("user.home") + File.separator + "Desktop" + File.separator + "agri_mall",
                System.getProperty("user.home") + File.separator + "workspace" + File.separator + "agri_mall",
                "C:" + File.separator + "Users" + File.separator + "Administrator" + File.separator + "Desktop" + File.separator + "agri_mall",
                "D:" + File.separator + "workspace" + File.separator + "agri_mall",
                "E:" + File.separator + "workspace" + File.separator + "agri_mall"
            };
            for (String commonPath : commonPaths) {
                File testRoot = new File(commonPath);
                if (testRoot.exists() && new File(testRoot, "pom.xml").exists()) {
                    projectRoot = testRoot.getAbsolutePath();
                    break;
                }
            }
        }
        
        // 如果所有方法都失败，抛出异常并提示配置
        if (projectRoot == null || projectRoot.isEmpty() || !new File(projectRoot, "pom.xml").exists()) {
            throw new RuntimeException("无法找到项目根目录。请在 src/main/resources/db.properties 中配置 upload.project.root 属性，例如：upload.project.root=C:\\Users\\Administrator\\Desktop\\agri_mall");
        }
        
        // 构建完整的upload路径：项目根目录/src/main/resources/upload
        String uploadPath = projectRoot + File.separator + "src" + File.separator + 
                           "main" + File.separator + "resources" + File.separator + UPLOAD_PATH;
        
        // 确保目录存在
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) {
            boolean created = uploadDir.mkdirs();
            if (!created) {
                throw new RuntimeException("无法创建上传目录: " + uploadPath);
            }
        }
        
        return uploadPath;
    }
    
    /**
     * 获取上传文件的访问URL
     */
    public static String getUploadUrl(HttpServletRequest request, String fileName) {
        return request.getContextPath() + "/upload/" + fileName;
    }
    
    /**
     * 上传多个图片文件
     * @param items 文件项列表（已解析的FileItem列表）
     * @param request HTTP请求（用于生成URL）
     * @param maxCount 最大上传数量
     * @return 上传成功的文件URL列表（逗号分隔）
     * @throws Exception 上传失败时抛出异常
     */
    public static String uploadImages(List<FileItem> items, HttpServletRequest request, int maxCount) throws Exception {
        if (items == null || items.isEmpty()) {
            return "";
        }
        
        // 获取上传路径
        String uploadPath = getUploadPath(request);
        List<String> uploadedUrls = new ArrayList<>();
        
        int imageCount = 0;
        for (FileItem item : items) {
            if (!item.isFormField() && item.getSize() > 0) {
                // 检查文件数量
                if (imageCount >= maxCount) {
                    throw new Exception("最多只能上传" + maxCount + "张图片");
                }
                
                // 检查文件类型
                String contentType = item.getContentType();
                if (contentType == null || !ALLOWED_IMAGE_TYPES.contains(contentType.toLowerCase())) {
                    throw new Exception("不支持的文件类型：" + contentType);
                }
                
                // 检查文件大小
                if (item.getSize() > MAX_FILE_SIZE) {
                    throw new Exception("文件大小不能超过5MB");
                }
                
                // 生成唯一文件名
                String originalFileName = item.getName();
                String fileExtension = "";
                int lastDotIndex = originalFileName.lastIndexOf('.');
                if (lastDotIndex > 0 && lastDotIndex < originalFileName.length() - 1) {
                    fileExtension = originalFileName.substring(lastDotIndex);
                }
                
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                String newFileName = sdf.format(new Date()) + "_" + 
                    UUID.randomUUID().toString().replace("-", "").substring(0, 8) + fileExtension;
                
                // 保存文件
                File uploadedFile = new File(uploadPath, newFileName);
                item.write(uploadedFile);
                
                // 生成访问URL
                String fileUrl = getUploadUrl(request, newFileName);
                uploadedUrls.add(fileUrl);
                imageCount++;
            }
        }
        
        // 返回逗号分隔的URL字符串
        return String.join(",", uploadedUrls);
    }
    
    /**
     * 下载文件
     * @param request HTTP请求
     * @param response HTTP响应
     * @param fileName 文件名
     * @throws IOException IO异常
     */
    public static void downloadFile(HttpServletRequest request, HttpServletResponse response, String fileName) throws IOException {
        String uploadPath = getUploadPath(request);
        File file = new File(uploadPath, fileName);
        
        if (!file.exists() || !file.isFile()) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            response.getWriter().print("文件不存在");
            return;
        }
        
        // 设置响应头（Content-Type由调用者设置）
        response.setHeader("Content-Disposition", "inline; filename=\"" + 
            new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + "\"");
        response.setContentLengthLong(file.length());
        
        // 输出文件
        try (InputStream in = new FileInputStream(file);
             OutputStream out = response.getOutputStream()) {
            IOUtils.copy(in, out);
        }
    }
    
    /**
     * 删除文件
     * @param request HTTP请求
     * @param fileName 文件名
     * @return 是否删除成功
     */
    public static boolean deleteFile(HttpServletRequest request, String fileName) {
        String uploadPath = getUploadPath(request);
        File file = new File(uploadPath, fileName);
        if (file.exists() && file.isFile()) {
            return file.delete();
        }
        return false;
    }
    
    /**
     * 删除多个文件（通过URL列表）
     * @param request HTTP请求
     * @param imageUrls 图片URL列表（逗号分隔）
     * @return 删除成功的数量
     */
    public static int deleteFiles(HttpServletRequest request, String imageUrls) {
        if (imageUrls == null || imageUrls.trim().isEmpty()) {
            return 0;
        }
        
        int deletedCount = 0;
        String[] urls = imageUrls.split(",");
        String uploadPath = getUploadPath(request);
        String contextPath = request.getContextPath() + "/upload/";
        
        for (String url : urls) {
            url = url.trim();
            if (url.startsWith(contextPath)) {
                String fileName = url.substring(contextPath.length());
                File file = new File(uploadPath, fileName);
                if (file.exists() && file.isFile() && file.delete()) {
                    deletedCount++;
                }
            }
        }
        
        return deletedCount;
    }
    
    /**
     * 获取上传路径常量（用于配置）
     */
    public static String getUploadPathConstant() {
        return UPLOAD_PATH;
    }
    
    /**
     * 获取最大文件大小常量（用于配置）
     */
    public static long getMaxFileSizeConstant() {
        return MAX_FILE_SIZE;
    }
}

